package com.sc.admin.core.api.web;


import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.sc.admin.core.bo.UserBo;
import com.sc.admin.core.service.SysAccountService;
import com.sc.admin.core.service.SysOrganizationService;
import com.sc.admin.core.service.SysUserService;
import com.sc.common.annotations.OperationLog;
import com.sc.common.annotations.WebApi;
import com.sc.common.context.DefaultBusinessContext;
import com.sc.common.dto.PageDto;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.account.SysAccount;
import com.sc.common.entity.admin.importexport.SysImportExport;
import com.sc.common.entity.admin.organization.SysOrganization;
import com.sc.common.entity.admin.organization.SysOrganizationSearch;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.entity.admin.user.SysUserList;
import com.sc.common.entity.admin.user.SysUserSearch;
import com.sc.common.entity.admin.userorganization.SysUserOrganizationSearch;
import com.sc.common.enums.ApplicationEnum;
import com.sc.common.enums.DataDictionaryEnum;
import com.sc.common.enums.OperationLogEnum;
import com.sc.common.exception.BusinessException;
import com.sc.common.util.CodeGenerator;
import com.sc.common.util.MyIdUtil;
import com.sc.common.util.MyStringUtils;
import com.sc.common.util.RC4;
import com.sc.common.util.cache.DataDictionaryUtil;
import com.sc.common.util.cache.SpringRedisTools;
import com.sc.mq.producer.Producer4routingKey;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 员工
 * Created by wust on 2019/5/9.
 */
@WebApi
@RequestMapping("/web/v1/UserController")
@RestController
public class UserController {
    @Autowired
    private SysUserService sysUserServiceImpl;

    @Autowired
    private SysOrganizationService sysOrganizationServiceImpl;

    @Autowired
    private SysAccountService sysAccountServiceImpl;

    @Autowired
    private SpringRedisTools springRedisTools;

    @Autowired
    private UserBo userBo;

    @Autowired
    private Producer4routingKey producer4routingKey;

    @Value("${spring.rabbitmq.importexcel.exchange.name}")
    private String exchangeName;

    @Value("${spring.rabbitmq.importexcel.routing-key}")
    private String routingKey;

    @Autowired
    private Environment environment;


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="分页查询",operationType= OperationLogEnum.Search)
    @RequestMapping(value = "/listPage",method = RequestMethod.POST)
    public WebResponseDto listPage(@RequestBody SysUserSearch search){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        if(ctx.isStaff()){ // 非管理员只能查看指定范围的数据
            search.setAgentId(ctx.getAgentId());
            search.setParentCompanyId(ctx.getParentCompanyId());
            search.setBranchCompanyId(ctx.getBranchCompanyId());
        }

        PageDto pageDto = search.getPageDto();
        List<SysUserList> list =  sysUserServiceImpl.selectByPageNumSize(search,pageDto.getPageNum(),pageDto.getPageSize()) == null ? null
                : (List<SysUserList>)sysUserServiceImpl.selectByPageNumSize(search,pageDto.getPageNum(),pageDto.getPageSize());
        if(CollectionUtils.isNotEmpty(list)){
            for (SysUserList userList : list) {
                userList.setSexLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getSex()));
                userList.setStatusLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getStatus()));
                userList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getType()));
            }
        }
        PageInfo page = new PageInfo(list);
        BeanUtils.copyProperties(page,pageDto);
        responseDto.setPage(pageDto);
        responseDto.setLstDto(list);
        return responseDto;
    }


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="分页查询",operationType= OperationLogEnum.Search)
    @RequestMapping(value = "/listPageByParentOrganization",method = RequestMethod.POST)
    public WebResponseDto listPageByParentOrganization(@RequestBody SysUserOrganizationSearch search){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        PageDto pageDto = search.getPageDto();
        List<SysUserList> list =  sysUserServiceImpl.listPageByParentOrganization(search,pageDto.getPageNum(),pageDto.getPageSize());
        if(CollectionUtils.isNotEmpty(list)){
            for (SysUserList userList : list) {
                userList.setSexLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getSex()));
                userList.setStatusLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getStatus()));
                userList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),userList.getType()));
            }
        }
        PageInfo page = new PageInfo(list);
        BeanUtils.copyProperties(page,pageDto);
        responseDto.setPage(pageDto);
        responseDto.setLstDto(list);
        return responseDto;
    }

    @RequestMapping(value = "/findByLoginName",method = RequestMethod.POST)
    public WebResponseDto findByLoginName(@RequestParam String loginName){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysAccount accountSearch = new SysAccount();
        accountSearch.setAccountCode(loginName);
        SysAccount account = sysAccountServiceImpl.selectOne(accountSearch);
        if(account == null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("该账号还没有注册到系统");
            return responseDto;
        }

        responseDto.setObj(account);
        return responseDto;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="新增",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "",method = RequestMethod.POST)
    public WebResponseDto create(@RequestBody SysUser user){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysUser userSearch = new SysUser();
        userSearch.setLoginName(user.getLoginName());
        SysUser userExist = sysUserServiceImpl.selectOne(userSearch);
        if(userExist != null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("该账号与系统现有账号有重复，请仔细核对");
            return responseDto;
        }

        SysAccount accountSearch = new SysAccount();
        accountSearch.setAccountCode(user.getLoginName());
        SysAccount account = sysAccountServiceImpl.selectOne(accountSearch);
        if (account == null) {
            String passwordRC4 = RC4.encry_RC4_string(SecureUtil.md5("123456").toUpperCase(), ApplicationEnum.LOGIN_RC4_KEY.getStringValue());
            account = new SysAccount();
            account.setId(MyIdUtil.getId());
            account.setAccountCode(user.getLoginName());
            account.setAccountName(user.getRealName());
            account.setPassword(passwordRC4);
            account.setType("A101703");
            account.setSource("Web");
            account.setCreaterId(ctx.getAccountId());
            account.setCreaterName(ctx.getAccountName());
            account.setCreateTime(new Date());
            account.setIsDeleted(0);
        }

        user.setId(account.getId());
        user.setAgentId(ctx.getAgentId());
        user.setStatus("A102901");
        user.setCreaterId(ctx.getAccountId());
        user.setCreaterName(ctx.getAccountName());
        user.setCreateTime(new Date());
        user.setIsDeleted(0);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("account",account);
        jsonObject.put("user",user);
        sysUserServiceImpl.create(jsonObject);
        return responseDto;
    }


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="更新",operationType= OperationLogEnum.Update)
    @RequestMapping(value = "",method = RequestMethod.PUT)
    public WebResponseDto update(@RequestBody SysUser sysUser){
        WebResponseDto mm = new WebResponseDto();

        if("A100201".equals(sysUser.getType())){
            throw new BusinessException("该账号已经被禁用，不允许修改！");
        }

        sysUserServiceImpl.update(sysUser);
        return mm;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="删除",operationType= OperationLogEnum.Delete)
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public WebResponseDto delete(@PathVariable Long id){
        WebResponseDto responseDto = new WebResponseDto();

        SysUserSearch sysUserSearch = new SysUserSearch();
        sysUserSearch.setId(id);
        List<SysUser> sysUserLists = sysUserServiceImpl.select(sysUserSearch);
        if(CollectionUtils.isNotEmpty(sysUserLists)){
            SysOrganizationSearch sysOrganizationSearch = new SysOrganizationSearch();
            sysOrganizationSearch.setRelationId(id);
            sysOrganizationSearch.setType(DataDictionaryEnum.ORGANIZATION_TYPE_USER.getStringValue());
            List<SysOrganization> sysOrganizationLists = sysOrganizationServiceImpl.select(sysOrganizationSearch);
            if(CollectionUtils.isNotEmpty(sysOrganizationLists)){
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("您要删除的数据存在组织架构关系中，不允许删除");
                return responseDto;
            }

            sysUserServiceImpl.delete(id);
        }
        return responseDto;
    }


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="邀请入职",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/inviteUser",method = RequestMethod.POST)
    public WebResponseDto inviteUser(@RequestBody SysUser sysUser){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysUser userSearch = new SysUser();
        userSearch.setLoginName(sysUser.getLoginName());
        SysUser user = sysUserServiceImpl.selectOne(userSearch);
        if(user != null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("系统已经存在此员工信息，不需要重复录入");
            return responseDto;
        }

        SysAccount accountSearch = new SysAccount();
        accountSearch.setAccountCode(sysUser.getLoginName());
        SysAccount account = sysAccountServiceImpl.selectOne(accountSearch);

        sysUser.setId(account.getId());
        sysUser.setAgentId(ctx.getAgentId());
        sysUser.setStatus("A102901");
        sysUser.setCreaterId(ctx.getAccountId());
        sysUser.setCreaterName(ctx.getAccountName());
        sysUser.setCreateTime(new Date());
        sysUserServiceImpl.create(sysUser);
        return responseDto;
    }

    /**
     *
     * @param request
     * @param multipartFile
     * @return
     */
    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_USER,businessName="导入",operationType= OperationLogEnum.Import)
    @RequestMapping(value = "/importByExcel",method= RequestMethod.POST)
    public WebResponseDto importByExcel (HttpServletRequest request, @RequestParam(value = "file" , required = true) MultipartFile multipartFile) {
        WebResponseDto mm = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        String xmlName = MyStringUtils.null2String(request.getParameter("xmlName"));
        if(StringUtils.isBlank(xmlName)){
            mm.setFlag(WebResponseDto.INFO_WARNING);
            mm.setMessage("上传文件失败，xmlName必须填。");
            return mm;
        }else if(!xmlName.matches("[A-Za-z0-9_]+")){
            mm.setFlag(WebResponseDto.INFO_WARNING);
            mm.setMessage("上传文件失败，xmlName只能是字母、数字、下划线或三者的组合。");
            return mm;
        }


        try {

            String batchNo = CodeGenerator.genImportExportCode();
            SysImportExport sysImportExport = new SysImportExport();
            sysImportExport.setBatchNo(batchNo);
            sysImportExport.setModuleName(xmlName);
            sysImportExport.setStartTime(new Date());
            sysImportExport.setOperationType("A100601");
            sysImportExport.setStatus("A100501");
            sysImportExport.setCreaterId(ctx.getAccountId());
            sysImportExport.setCreaterName(ctx.getAccountName());
            sysImportExport.setCreateTime(new Date());


            JSONObject jsonObject = new JSONObject();
            jsonObject.put("xmlName",xmlName);
            jsonObject.put("fileBytes",multipartFile.getBytes());
            jsonObject.put("sysImportExport",sysImportExport);
            jsonObject.put("ctx",DefaultBusinessContext.getContext());
            jsonObject.put("spring.application.name",environment.getProperty("spring.application.name"));

            producer4routingKey.send(exchangeName,routingKey,jsonObject);
        }catch (IOException e){
            mm.setFlag(WebResponseDto.INFO_ERROR);
            mm.setMessage("导入失败，转换文件失败。");
            return mm;
        }
        return mm;
    }

    @RequestMapping(value = "/buildCascader",method = RequestMethod.POST)
    public WebResponseDto buildCascader(){
        WebResponseDto responseDto = new WebResponseDto();
        JSONArray jsonArray = userBo.buildCascader();
        responseDto.setObj(jsonArray);
        return responseDto;
    }
}
